package com.cskaoyan.javase.oop3._3local._1basic;

/**
 * 仍然先明确两点:
 *      1.局部内部类仅在作用域内部生效,必须在作用域内部创建它的对象,才能生效
 *          这说明,在这个作用域外部都不能访问这个局部内部类了
 *      2.局部内部类仍然是内部类,所以它和外围类还是好兄弟,但是情况有变:
 *          1.局部内部类还是无条件访问外围类成员
 *          2.但是外围类必须在装有局部内部类的那个作用域内部(方法内部)才能够访问局部内部类成员.
 *
 * 局部内部类的访问特点，我们仍然主要从以下几个角度研究：
 * 局部内部类内部访问外围类
 *      这时要区分情况,按照情况的不同:
 *          1.如果是处在外围类的成员方法中的局部内部类
 *              会将外围类对象的引用作为自身对象的成员变量持有
 *              所以这时,可以直接访问外围类成员
 *
 *              此时局部内部类的成员方法中,存在两个对象:
 *                  a.this指向当前自身局部内部类对象
 *                  b.外围类类名.this指向外围类对象
 *
 *          2.如果是处在外围类的静态成员方法中的局部内部类
 *                此时不存在外围类对象,所以这时局部内部类对象,不会持有外围类对象的引用
 *                所以这时想要访问外围类成员,创建它的对象即可.
 *
 * 外围类访问局部内部类成员
 *      首先,必须在装有局部内部类的作用域内部能够访问
 *      访问时new对象即可
 *      访问不受访问权限限制
 *
 *      但是出了作用域,就无法访问局部内部类
 *
 * 外部类访问局部内部类成员
 *      不能访问,访问不到
 *      局部内部类在作用域外部绝对隐藏的
 *
 * 局部内部类访问外部类成员
 *      可以访问,创建对象,受访问权限限制
 *
 * @since 11:43
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        EnclosedClazz ec = new EnclosedClazz();
        ec.test();

        EnclosedClazz.testStatic();
    }
}

class EnclosedClazz {
    int a = 10;
    private int b = 20;
    static int c = 30;
    static final int D = 40;

    public void test() {
        int var = 100;
        // 定义局部内部类
        class Inner {
            int a = 10;
            private int b = 20;

            public void testInner(int a) {
                System.out.println(var);
                System.out.println(a);
                System.out.println(this.a);
                System.out.println(EnclosedClazz.this.a);
                System.out.println(b);
                System.out.println(EnclosedClazz.c);
                System.out.println(EnclosedClazz.D);
            }
        }
        Inner i = new Inner();
    }

    public static void testStatic() {
        // 定义局部内部类
        class Inner {
            private int a = 10;

            public void testInner() {
                EnclosedClazz ec = new EnclosedClazz();
                System.out.println(ec.a);
                System.out.println(ec.b);
            }
        }
        Inner i = new Inner();
        System.out.println(i.a);
    }

}